/**
 * 基于canvas对象导出类，使用canvas对象初始化类后可持续修改
 */
export default class {
    constructor(context) {
        this.context = context
    }
    /**
     * 绘制圆角矩形
     * @param {number} x X轴
     * @param {number} y y轴
     * @param {number} w 宽
     * @param {number} h 高
     * @param {number} r 半径
     * @param {string} color 颜色
     */
    roundRectColor(x, y, w, h, r, color) {
        this.context.save()
        this.context.setFillStyle(color)
        this.context.setStrokeStyle(color)
        this.context.beginPath()
        this.context.setLineJoin('round') // 交点设置成圆角
        this.context.setLineWidth(r)
        this.context.strokeRect(x + r / 2, y + r / 2, w - r, h - r)
        this.context.fillRect(x + r, y + r, w - r * 2, h - r * 2)
        this.context.stroke()
        this.context.closePath()
        this.context.clip()
        this.context.restore()
    }
    /**
     * 绘制图片圆角
     * @param {*} x 图片的x坐标
     * @param {*} y 图片的y坐标
     * @param {*} w 图片宽度
     * @param {*} h 图片高度
     * @param {*} r 图片圆角
     * @param {*} path 图片
     * @param {*} hasArc 是否圆角，true:圆角，false:非圆角，方向[topLeft, topRight, bottomRight, bottomLeft]
     *            [true, true, false, false]
     * 
     * ctx.arc(圆心x：31, 圆心y：31, 半径：18, 周长三点钟方向开始：0, 周长弧度：2 * Math.PI)
     */
    circleImage(x, y, w, h, r, path, hasArc = [true, true, true, true]) {
        this.context.save()
        this.context.beginPath()
        if (hasArc[0]) this.context.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5)
        else this.context.arc(x, y, 0, y, 0)

        if (hasArc[1]) this.context.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2)
        else this.context.arc(y, x, 0, x, 0)

        if (hasArc[2]) this.context.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5)
        else this.context.arc(x + h, y + w + h, 0, x, 0)

        if (hasArc[3]) this.context.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI)
        else this.context.arc(x, y + h, 0, y, 0)

        this.context.clip()
        this.context.drawImage(path, x, y, w, h)
        // 恢复之前保存的绘图上下文
        this.context.restore()
    }
    /**
     * 绘制圆形
     * @param {number} x X轴
     * @param {number} y y轴
     * @param {number} w 宽
     * @param {string} color 颜色
     */
    circleRectColor(x, y, w, color) {
        this.context.save()
        this.context.setFillStyle(color)
        this.context.setStrokeStyle(color)
        this.context.beginPath()
        this.context.arc(x + w / 2, y + w / 2, w / 2, 0, Math.PI * 2, false)
        this.context.fill()
        this.context.stroke()
        this.context.closePath()
        this.context.clip()
        this.context.restore()
    }
    /**
     * 绘制圆形图片
     * @param {number} x X轴
     * @param {number} y y轴
     * @param {number} w 宽
     * @param {string} path 图像路径
     * @param {string} color 颜色
     */
    drawRoundImage(x, y, w, path, color) {
        this.context.save()
        this.context.beginPath()
        this.context.fillStyle = color
        this.context.arc(x + w / 2, y + w / 2, w / 2, 0, Math.PI * 2, false)
        this.context.closePath()
        this.context.fill()
        this.context.clip()
        this.context.drawImage(path, x, y, w, w)
        this.context.restore()
    }
    /**
     * 绘制高度裁剪图片
     * @param {number} x X轴
     * @param {number} y y轴
     * @param {number} w 宽
     * @param {number} h 高
     * @param {number} wh 图像高度
     * @param {string} path 图像路径
     */
    drawHeightCutImage(x, y, w, h, wh, path) {
        this.context.save()
        this.context.beginPath()
        this.context.rect(x, y, w, h)
        this.context.closePath()
        this.context.fill()
        this.context.clip()
        this.context.drawImage(path, x, y, w, wh)
        this.context.restore()
    }
    /**
     * 绘制矩形
     * @param {number} x X轴
     * @param {number} y y轴
     * @param {number} w 宽
     * @param {number} h 高
     * @param {string} color 颜色
     */
    fillRect(x, y, w, h, color) {
        this.context.save()
        this.context.setFillStyle(color)
        this.context.fillRect(x, y, w, h)
        this.context.restore()
    }
    /**
     * 绘制文本
     * @param {string} text 文本内容
     * @param {number} x x轴
     * @param {number} y y轴
     * @param {string} color 文字颜色
     * @param {number} size 文字字号
     * @param {string} align 居中类型
     * @param {boolean} bold 是否加粗
     */
    fillText(text, x, y, color, size, align = 'left', bold = false) {
        this.context.save()
        this.context.setFillStyle(color)
        this.context.setFontSize(size)
        this.context.font = (bold ? 'bold ' : '') + size + 'px ' + (bold ? 'sans-serif' : 'serif')
        this.context.textAlign = align
        this.context.fillText(text, x, y)
        this.context.restore()
    }
    /**
     * 绘制需要换行的长文本
     * @param {string} str 文本内容
     * @param {number} x x轴
     * @param {number} y y轴
     * @param {number} fontNum 每行多少字
     * @param {number} row 共几行
     * @param {string} color 文本颜色
     * @param {number} size 文字大小
     */
    fillLongText(str, x, y, fontNum, row, color, size) {
        str = str.replace(/[\r\n]/g, '||')
        const strArr = str.split('||')
        let arr = []
        for (const index in strArr) {
            if (index > row) {
                break
            }
            for (let i = 0, l = strArr[index].length; i < l / fontNum; i++) {
                let temporary = strArr[index].slice(
                    fontNum * i,
                    fontNum * (i + 1)
                )
                arr.push(temporary)
            }
        }
        for (let i = 0; i < row && i < arr.length; i++) {
            if (arr.length > row && i === row - 1) {
                arr[i] += '...'
            }
            this.fillText(arr[i], x, y + i * (size + 6), color, size)
        }
    }

    /**
     * 绘制圆形
     * @param {number} x X轴
     * @param {number} y y轴
     * @param {number} w 宽
     * @param {string} color 颜色
     */
    circleRectColor(x, y, w, color) {
        this.context.save()
        this.context.setFillStyle(color)
        this.context.setStrokeStyle(color)
        this.context.beginPath()
        this.context.arc(x + w / 2, y + w / 2, w / 2, 0, Math.PI * 2, false)
        this.context.fill()
        this.context.stroke()
        this.context.closePath()
        this.context.clip()
        this.context.restore()
    }

    /**
     * 绘制图片圆角
     * @param {*} x 图片的x坐标
     * @param {*} y 图片的y坐标
     * @param {*} w 图片宽度
     * @param {*} h 图片高度
     * @param {*} r 图片圆角
     * @param {*} path 图片
     * @param {*} hasArc 是否圆角，true:圆角，false:非圆角，方向[topLeft, topRight, bottomRight, bottomLeft]
     *            [true, true, false, false]
     * 
     * ctx.arc(圆心x：31, 圆心y：31, 半径：18, 周长三点钟方向开始：0, 周长弧度：2 * Math.PI)
     */
    circleImage(x, y, w, h, r, path, hasArc = [true, true, true, true]) {
        this.context.save()
        this.context.beginPath()
        if (hasArc[0]) this.context.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5)
        else this.context.arc(x, y, 0, y, 0)

        if (hasArc[1]) this.context.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2)
        else this.context.arc(y, x, 0, x, 0)

        if (hasArc[2]) this.context.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5)
        else this.context.arc(x + h, y + w + h, 0, x, 0)

        if (hasArc[3]) this.context.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI)
        else this.context.arc(x, y + h, 0, y, 0)

        this.context.clip()
        this.context.drawImage(path, x, y, w, h)
        // 恢复之前保存的绘图上下文
        this.context.restore()
    }
}

export class Canvas2d {
    constructor(id) {
        return new Promise(resolve => {
            wx.createSelectorQuery().select(id).fields({
                node: true,
                size: true,
            }).exec(async ele => {
                ele = ele[0]
                const width = ele.width
                const height = ele.height
                const dpr = wx.getSystemInfoSync().pixelRatio
                ele.node.width = width * dpr
                ele.node.height = height * dpr
                this.context = ele.node.getContext('2d')
                this.context.scale(dpr, dpr)
                this.node = ele.node
                this.elem = ele
                resolve(this)
            })
        })
    }
    /**
     * 绘制圆角矩形
     * @param {number} x X轴
     * @param {number} y y轴
     * @param {number} w 宽
     * @param {number} h 高
     * @param {number} r 半径
     * @param {string} color 颜色
     */
    roundRectColor(x, y, w, h, r, color) {
        this.context.save()
        this.context.fillStyle = color
        this.context.setStrokeStyle(color)
        this.context.beginPath()
        this.context.setLineJoin('round') // 交点设置成圆角
        this.context.setLineWidth(r)
        this.context.strokeRect(x + r / 2, y + r / 2, w - r, h - r)
        this.context.fillRect(x + r, y + r, w - r * 2, h - r * 2)
        this.context.stroke()
        this.context.closePath()
        this.context.clip()
        this.context.restore()
    }
    /**
     * 绘制圆形图片
     * @param {number} x X轴
     * @param {number} y y轴
     * @param {number} w 宽
     * @param {string} path 图像路径
     * @param {string} color 颜色
     */
    drawRoundImage(x, y, w, path, color) {
        return new Promise(resolve => {
            const img = this.node.createImage()
            img.src = path
            img.onload = () => {
                this.context.save()
                this.context.beginPath()
                this.context.fillStyle = color
                this.context.arc(x + w / 2, y + w / 2, w / 2, 0, Math.PI * 2, false)
                this.context.closePath()
                this.context.fill()
                this.context.clip()
                this.context.drawImage(img, x, y, w, w)
                this.context.restore()
                resolve()
            }
        })
    }
    /**
     * 绘制高度裁剪图片
     * @param {number} x X轴
     * @param {number} y y轴
     * @param {number} w 宽
     * @param {number} h 高
     * @param {number} wh 图像高度
     * @param {string} path 图像路径
     */
    drawHeightCutImage(x, y, w, h, wh, path) {
        return new Promise(resolve => {
            const img = this.node.createImage()
            img.src = path
            img.onload = () => {
                this.context.save()
                this.context.beginPath()
                this.context.rect(x, y, w, h)
                this.context.closePath()
                this.context.fill()
                this.context.clip()
                this.context.drawImage(img, x, y, w, wh)
                this.context.restore()
                resolve()
            }
        })
    }
    /**
     * 绘制矩形
     * @param {number} x X轴
     * @param {number} y y轴
     * @param {number} w 宽
     * @param {number} h 高
     * @param {string} color 颜色
     */
    fillRect(x, y, w, h, color) {
        this.context.save()
        this.context.fillStyle = color
        this.context.fillRect(x, y, w, h)
        this.context.restore()
    }
    /**
     * 绘制文本
     * @param {string} text 文本内容
     * @param {number} x x轴
     * @param {number} y y轴
     * @param {string} color 文字颜色
     * @param {number} size 文字字号
     * @param {string} align 居中类型
     * @param {boolean} bold 是否加粗
     */
    fillText(text, x, y, color, size, align = 'left', bold = false) {
        this.context.save()
        this.context.fillStyle = color
        this.context.fontSize = size
        this.context.font = (bold ? 'bold ' : '') + size + 'px boldface, Songti SC'
        this.context.textAlign = align
        this.context.fillText(text, x, y)
        this.context.restore()
    }
    /**
     * 绘制需要换行的长文本
     * @param {string} str 文本内容
     * @param {number} x x轴
     * @param {number} y y轴
     * @param {number} fontNum 每行多少字
     * @param {number} row 共几行
     * @param {string} color 文本颜色
     * @param {number} size 文字大小
     */
    fillLongText(str, x, y, fontNum, row, color, size) {
        str = str.replace(/[\r\n]/g, '||')
        const strArr = str.split('||')
        let arr = []
        for (const index in strArr) {
            if (index > row) {
                break
            }
            for (let i = 0, l = strArr[index].length; i < l / fontNum; i++) {
                let temporary = strArr[index].slice(
                    fontNum * i,
                    fontNum * (i + 1)
                )
                arr.push(temporary)
            }
        }
        for (let i = 0; i < row && i < arr.length; i++) {
            if (arr.length > row && i === row - 1) {
                arr[i] += '...'
            }
            this.fillText(arr[i], x, y + i * (size + 6), color, size)
        }
    }
}